#include <boost/python.hpp>
#include "BtreePlus.h"
#include "Pager.h"
#include "Page.h"
#include "Cache.h"
#include "UnitTest.h"

using namespace boost::python;

BOOST_PYTHON_MODULE(btreePlus){
    class_<Cache>("Cache", init<int64_t, int32_t>())
        .def("init", &Cache::init)
        .def("deinit", &Cache::deinit)
        .def("allocate", &Cache::allocate, return_internal_reference<>())
        .def("acquire", &Cache::acquire, return_internal_reference<>())
        .def("release", &Cache::release)
        .def("usedPageCount", &Cache::usedPageCount)
        .def("freePageCount", &Cache::freePageCount)
        ;

    int (Page::*writeString_string)(const std::string &)  = &Page::writeString;
    char* (Page::*getAddr_offset)(const int32_t offset) const = & Page::getAddr;

    class_<Page>("Page", init<PageNumberType, char *, const int32_t>())
        .def("writeString", writeString_string)
        .def("hex", &Page::hex)
        .def("__str__", &Page::toString)
        .def("getAddr", getAddr_offset, return_value_policy<return_opaque_pointer>())
        .def("isAllocated", &Page::isAllocated)
        .def("isSync", &Page::isSync)
        .def("isDirty", &Page::isDirty)
        .def("newPage", &Page::newPage, return_internal_reference<>())
        .staticmethod("newPage")
        .def("freePage", &Page::freePage)
        .staticmethod("freePage")
        .add_property("pageNo", &Page::getNo)
        ;

    class_<Pager>("Pager", init<const std::string &, const int64_t, const int32_t>())
        .def("open", &Pager::open)
        .def("close", &Pager::close)
        .def("pageSize", &Pager::getPageSize)
        .def("allocPage", &Pager::allocPage, return_internal_reference<>())
        .def("releasePage", &Pager::releasePage)
        .def("readPage", &Pager::readPage, return_internal_reference<>())
        .def("writePage", &Pager::writePage)
        .def("savePoint", &Pager::savePoint)
        .def("__str__", &Pager::toString)
        ;

    class_<UnitTest>("UnitTest")
        .def("run", &UnitTest::run)
        ;
    
//    class_<Util>("RawTypeUtil")
//        .def("delete", RawTypeUtil::deleteRaw)
//        .staticmethod("delete")
//        .def("newInt8",     &RawTypeUtil::newInt8)
//        .staticmethod("newInt8")
//        .def("newInt16",    &RawTypeUtil::newInt16)
//        .staticmethod("newInt16")
//        .def("newInt32",    &RawTypeUtil::newInt32)
//        .staticmethod("newInt32")
//        .def("newInt64",    &RawTypeUtil::newInt64)
//        .staticmethod("newInt64")
//        .def("newUint8",    &RawTypeUtil::newUint8)
//        .staticmethod("newUint8")
//        .def("newUint16",   &RawTypeUtil::newUint16)
//        .staticmethod("newUint16")
//        .def("newUint32",   &RawTypeUtil::newUint32)
//        .staticmethod("newUint32")
//        .def("newUint64",   &RawTypeUtil::newUint64)
//        .staticmethod("newUint64")
//        ;

    class_<BtreePlus>("BtreePlus", init<const std::string &>())
        .def("open", &BtreePlus::open)
        .def("close", &BtreePlus::close)
        .def("insert", &BtreePlus::insert)
        .def("delete", &BtreePlus::del)
        .def("find", &BtreePlus::find)
        .def("__str__", &BtreePlus::toString)
        ;
}

